package com.kunyi.web.service.file.core.handel.Impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.system.SystemUtil;
import com.kunyi.web.service.file.core.constant.FileRedisLockConstant;
import com.kunyi.web.service.file.core.enums.KunyiRepositoryTypeEnum;
import com.kunyi.web.service.file.core.handel.FileLoginParams;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @ClassName KunyiLocalRepository
 * @Description 本地文件操作具体实现
 * @Author zhenguo.zhuang
 * @Date 2024/5/28 17:46
 * @Version 1.0
 */
@Slf4j
@Scope("prototype")
@Component("localRepository")
public class KunyiLocalRepository extends KunyiRepositoryAbstract {
    public static final String LINUX_SEPARATOR = "/";
    public static final String WINDOWS_SEPARATOR = "\\";
    public String LINUX_ROOT_PATH;
    public String WINDOWS_ROOT_PATH;


    /**
     * 系统类型，windows或linux
     */
    private static final String osType;

    /**
     * 初始化时获取存储类型
     */
    static {
        String osName = SystemUtil.getOsInfo().getName();
        if (StrUtil.containsIgnoreCase(osName, "windows")) {
            osType = "windows";
        } else if (StrUtil.containsIgnoreCase(osName, "linux")) {
            osType = "linux";
        } else {
            throw new RuntimeException("未知的操作系统类型:" + osName + ",本地文件存储初始化失败");
        }
    }

    @Override
    public boolean login(FileLoginParams loginParams) throws RuntimeException {
        super.redisService = loginParams.getRedisService();
        super.uploadService = loginParams.getService();
        super.URL=loginParams.getUrl();
        RLock lock = redisService.lock(FileRedisLockConstant.LOCK_OBJECT_STORAGE_PREFIX + "local_login");
        try {
            LINUX_ROOT_PATH = loginParams.getLinuxRootPath();
            WINDOWS_ROOT_PATH = loginParams.getWindowsRootPath();
            if (osType.equals("windows")) {
                super.osSeparator = WINDOWS_SEPARATOR;
                super.rootPath = WINDOWS_ROOT_PATH;
                return true;
            } else if (osType.equals("linux")) {
                super.osSeparator = LINUX_SEPARATOR;
                super.rootPath = LINUX_ROOT_PATH;
                return true;
            }
        }catch (Exception e){
            log.error(e.toString(), e);
            throw new RuntimeException("local初始化失败", e);
        }finally {
            redisService.unLock(lock);
        }

        return false;
    }

    @Override
    void loginInSpecific(String accessKeyId, String accessKeySecret, String endPoint) throws Exception {
    }

    @Override
    InputStream readStreamsSpecific(String filePath) throws Exception {
        File file = new File(filePath);
        FileInputStream inputStream = new FileInputStream(file);
        return inputStream;
    }


    @Override
    boolean isFileExistSpecific(String filePath) throws RuntimeException {
        File folder = new File(filePath);
        return folder.exists();
    }

    @Override
    boolean createDirSpecific(String filePath) throws RuntimeException {
        File folder = new File(filePath);
        return folder.mkdirs();
    }

    @Override
    void uploadSpecific(String filePath,String fileName,String appendFilePath, InputStream inputStream , Long length,MultipartFile multipartFile,File file) throws RuntimeException, IOException {
        if (ObjectUtil.isNull(multipartFile)){
            File file1 = new File(appendFilePath);
            FileUtil.copy(file,file1, true);
        }else {
            multipartFile.transferTo(new File(filePath, fileName));
        }
    }

    @Override
    boolean deleteFileSpecific(String filePath) throws RuntimeException {
        if (FileUtil.isFile(filePath)) {
            FileUtil.del(filePath);
        }
        return true;
    }

    @Override
    KunyiRepositoryTypeEnum type() {
        return KunyiRepositoryTypeEnum.LOCAL;
    }
}
